package cate.game.activity.commonstarup;


import cate.common.table.activity.commonstarup.CommonStarUpRow;
import cate.common.table.d.GDActivity;
import cate.common.table.d.GDFunc;
import cate.common.table.d.GDOperation;
import cate.common.table.item.hero.row.HeroBaseRow;
import cate.common.table.pay.PayItemRow;
import cate.common.util.GameResult;
import cate.game.activity.base.core.RoleActivitySingle;
import cate.game.activity.commonstarup.msg.CommonStarUpGiftInfoResp;
import cate.game.activity.commonstarup.po.CommonStarUpGiftBag;
import cate.game.res.MixRes;
import cate.game.res.MixResAdder;
import cate.game.res.MixResItem;
import cate.game.role.Role;
import cate.game.role.bag.hero.Hero;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;

import java.beans.Transient;
import java.util.*;

public class CommonStarUpGiftActivity extends RoleActivitySingle {
    @NoteField("礼包")
    public Map<Integer, CommonStarUpGiftBag> giftPackMap;
    @NoteField("key:英雄原型id,value:礼包开启时间")
    public Map<Integer, Long> heroStartMap;

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (giftPackMap == null) {
            giftPackMap = new HashMap<>();
        }
        giftPackMap.values().forEach(item -> {
            item.initialize(role);
        });
        if (heroStartMap == null) {
            heroStartMap = new HashMap<>();
        }
    }

    @Override
    public void onEnter() {
        super.onEnter();
    }

    @Override
    public void onRoleOpen() {

    }

    @Override
    public void onRoleEnd() {

    }

    @Override
    public void initSend() {
        noticeUpdate();
    }

    public void updateAvailable(String uid) {
        Hero item = role.getBag().hero.getItem(uid);
        if (item == null) {
            return;
        }
        HeroBaseRow tpl = item.getTpl(role.getGame());
        if (tpl == null) {
            return;
        }
        CommonStarUpRow row = role.getGame().table.commonStarUp.commonStarUp.get(item.tid);
        if (row == null) {
            return;
        }
        if (row.configId != configTid()) {
            return;
        }
        if (giftPackMap.containsKey(item.tid) && (row.visible == 1 || heroStartMap.containsKey(tpl.protoId))) {
            tryEnablePacks(tpl);
        }
    }

    public void tryEnablePacks(HeroBaseRow tpl) {
        for (int key : giftPackMap.keySet()) {
            CommonStarUpRow starUpRow = role.getGame().table.commonStarUp.commonStarUp.get(key);
            HeroBaseRow row = role.getGame().table.hero.base.get(key);
            if (row == null) {
                continue;
            }
            if (row.protoId == tpl.protoId && row.star <= tpl.star && starUpRow.visible == 1) {
                giftPackMap.get(key).enablePack();
            }

        }
        if (!heroStartMap.containsKey(tpl.protoId)) {
            heroStartMap.put(tpl.protoId, game().time.now());
        }
        noticeUpdate();
    }

    @Override
    public GameResult<Void> allowPay(PayItemRow pir) {
        GameResult<Void> r = new GameResult<>();
        int tid = pir.funcSubId;
        if (!giftPackMap.containsKey(tid)) {
            return r.fail("此奖励未激活");
        }
        CommonStarUpRow config = getConfig(tid);
        if (config == null) {
            return r.fail("未找到活动配置");
        }
        if (!giftPackMap.get(tid).available) {
            return r.fail("无购买资格");
        }
        HeroBaseRow baseRow = getBaseRow(tid);
        if (baseRow == null) {
            return r.fail("未找到英雄基础配置");
        }
        if (heroStartMap.get(baseRow.protoId) <= game().time.now() - config.cycle) {
            return r.fail("此英雄礼包已过期");
        }
        if (config.limit != -1) {
            if (giftPackMap.get(tid).buyTimes >= config.limit) {
                return r.fail("限购次数不足");
            }
        }
        if (config.buyType != GDActivity.SHOP_TYPE_PAY) {
            return r.fail("不支持此购买模式");
        }
        MixRes rewardRes = giftPackMap.get(tid).getPackReward();
        if (rewardRes.isEmpty()) {
            return r.fail("奖励为空");
        }
        return r.success();
    }

    @Override
    public void onPaySuccess(PayItemRow payItemRow) {
        CommonStarUpRow config = getConfig(payItemRow.funcSubId);
        if (config == null) {
            return;
        }
        MixRes reward = giftPackMap.get(payItemRow.funcSubId).getPackReward();
        EcResult exe = new MixResAdder().setRes(reward)
                .setOperation(getGDOperation())
                .setOperationSub(payItemRow.funcSubId)
                .setDialogReward(true)
                .setSendMailWhenFull(true)
                .exe(role);
        giftPackMap.get(payItemRow.funcSubId).addBuyTimes();
        noticeUpdate();
    }

    public void noticeUpdate() {
        role.sendNow(new CommonStarUpGiftInfoResp(this));
    }

    @Override
    public void excelCheck() {
        Map<Integer, CommonStarUpRow> allConfigs = getConfigs();
        if (allConfigs.isEmpty()) {
            giftPackMap.clear();
            return;
        }
        giftPackMap.entrySet().removeIf(kv -> !allConfigs.containsKey(kv.getKey()));
        for (CommonStarUpRow config : allConfigs.values()) {
            if (!giftPackMap.containsKey(config.id)) {
                CommonStarUpGiftBag pack = new CommonStarUpGiftBag(config.id, false, false, 0);
                pack.initialize(role);
                giftPackMap.put(config.id, pack);
            }
        }
    }


    @JsonIgnore
    private Map<Integer, CommonStarUpRow> getConfigs() {
        Map<Integer, CommonStarUpRow> retMap = new HashMap<>();
        switch (funcId()) {
            case GDFunc.COMMON_STAR_UP: {
                for (CommonStarUpRow config : role.getGame().table.commonStarUp.commonStarUp.getList()) {
                    if (config.configId == configTid()) {
                        retMap.put(config.id, config);
                    }
                }
            }
            break;
        }
        return retMap;
    }

    @JsonIgnore
    @Transient
    private CommonStarUpRow getConfig(int tid) {
        switch (funcId()) {
            case GDFunc.COMMON_STAR_UP:
                return role.getGame().table.commonStarUp.commonStarUp.get(tid);
        }
        return null;
    }

    @JsonIgnore
    @Transient
    private HeroBaseRow getBaseRow(int tid) {
        switch (funcId()) {
            case GDFunc.COMMON_STAR_UP:
                return role.getGame().table.hero.base.get(tid);
        }
        return null;
    }

    @JsonIgnore
    @Transient
    private int getGDOperation() {
        switch (funcId()) {
            case GDFunc.COMMON_STAR_UP:
                return GDOperation.COMMON_STAR_UP;
        }
        return GDOperation.NULL;
    }

    @JsonIgnore
    @Transient
    public GameResult<CommonStarUpGiftActivity> getReward(int tid) {
        GameResult<CommonStarUpGiftActivity> r = new GameResult<>();
        r.data = this;
        CommonStarUpRow config = getConfig(tid);
        if (config == null) {
            return r.fail("未找到活动配置");
        }
        HeroBaseRow baseRow = getBaseRow(tid);
        if (baseRow == null) {
            return r.fail("未找到英雄基础配置");
        }
        if (heroStartMap.get(baseRow.protoId) <= game().time.now() - config.cycle) {
            return r.fail("此英雄礼包已过期");
        }
        if (giftPackMap.get(tid).got) {
            return r.fail("已领取过该奖励");
        }
        if (!giftPackMap.get(tid).available) {
            return r.fail("无领取该奖励资格");
        }
        MixRes rewardRes = new MixRes(giftPackMap.get(tid).getRow().freeReward);
        if (rewardRes.isEmpty()) {
            return r.fail("奖励为空");
        }
        EcResult exe = new MixResAdder().setRes(rewardRes)
                .setOperation(getGDOperation())
                .setOperationSub(tid)
                .setDialogReward(true)
                .setSendMailWhenFull(true)
                .exe(role);
        giftPackMap.get(tid).isGot();
        return r.success();
    }

    public GameResult<CommonStarUpGiftActivity> buyItem(int tid, int num) {
        GameResult<CommonStarUpGiftActivity> r = new GameResult<>();
        r.data = this;
        if (!giftPackMap.containsKey(tid)) {
            return r.fail("此奖励未激活");
        }
        CommonStarUpRow config = getConfig(tid);
        if (config == null) {
            return r.fail("未找到活动配置");
        }
        HeroBaseRow baseRow = getBaseRow(tid);
        if (baseRow == null) {
            return r.fail("未找到英雄基础配置");
        }
        if (heroStartMap.get(baseRow.protoId) <= game().time.now() - config.cycle) {
            return r.fail("此英雄礼包已过期");
        }
        if (config.limit != -1) {
            if (giftPackMap.get(tid).buyTimes > config.limit - num) {
                return r.fail("限购次数不足");
            }
        }
        if (config.buyType != GDActivity.SHOP_TYPE_ITEM_COST) {
            return r.fail("不支持此购买模式");
        }

        MixRes rewardRes = giftPackMap.get(tid).getPackReward();
        if (rewardRes.isEmpty()) {
            return r.fail("奖励为空");
        }
        MixRes costRes = new MixRes(config.cost);
        if (!costRes.isEmpty()) {
            costRes.items.forEach(item -> item.num *= num);
            EcResult<MixResItem> r_res = costRes.consumeCheck(role, null);
            if (!r_res.ok()) {
                return r.fail(r_res.message);
            }
            costRes.consume(role);
        }
        provideReward(tid, num);
        return r.success();
    }

    private void provideReward(int tid, int num) {
        if (!giftPackMap.containsKey(tid)) {
            return;
        }
        CommonStarUpRow config = getConfig(tid);
        if (config == null) {
            return;
        }
        MixRes rewardRes = giftPackMap.get(tid).getPackReward();
        if (rewardRes.isEmpty()) {
            return;
        }
        rewardRes.items.forEach(item -> item.num *= num);
        EcResult exe = new MixResAdder().setRes(rewardRes)
                .setOperation(getGDOperation())
                .setOperationSub(tid)
                .setDialogReward(true)
                .setSendMailWhenFull(true)
                .exe(role);
        giftPackMap.get(tid).addBuyTimes();
    }
}
